#
# Copyright 2023 The titan-search Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
####################################################################################
# generate by kmcmake package manager tools for EA
# https://gitee.com/kumo-pub/kmpkg
####################################################################################
cmake_minimum_required(VERSION 3.24)

project(krpc CXX C)

option(${PROJECT_NAME}_IS_TOP_PROJECT "krpc project is the top level project or not" ON)

get_property(not_top DIRECTORY PROPERTY PARENT_DIRECTORY)
if (not_top)
    set(${PROJECT_NAME}_IS_TOP_PROJECT OFF)
endif ()

set(PROJECT_DESCRIPTION "Hercules is an ahead of time compiler for a subset of the Python language framework.")
set(PROJECT_VERSION_MAJOR 0)
set(PROJECT_VERSION_MINOR 7)
set(PROJECT_VERSION_PATCH 1)
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")

set(${PROJECT_NAME}_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(${PROJECT_NAME}_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(${PROJECT_NAME}_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(${PROJECT_NAME}_VERSION ${PROJECT_VERSION})

string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UP)


set(KMCMAKE_VERSION 0.6.0)
set(KMCMAKE_CMAKE_VERSION 0.6.0)

list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/kmcmake)
##################################################################
# add this for ${PROJECT_NAME} 's cmake include
##################################################################
list(APPEND CMAKE_MODULE_PATH ${${PROJECT_NAME}_SOURCE_DIR}/cmake)
#######################################################################
# warning
# in kmcmake directory, caution to modify files in that dir
######################################################################
include(kmcmake_module)
option(BUILD_RPC_TOOLS "install rpc tools" ON)
##################################################################
#
# your cmake directory ${PROJECT_SOURCE_DIR}/cmake, do things here
#################################################################
include(krpc_deps)
include(krpc_cxx_config)
include(krpc_test)

string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_BUILD_TYPE)
configure_file(${PROJECT_SOURCE_DIR}/krpc/version.h.in ${PROJECT_SOURCE_DIR}/krpc/version.h @ONLY)

set(KUTIL_SOURCES
        ${PROJECT_SOURCE_DIR}/krpc/utility/third_party/dmg_fp/g_fmt.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/third_party/dmg_fp/dtoa_wrapper.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/third_party/dynamic_annotations/dynamic_annotations.c
        ${PROJECT_SOURCE_DIR}/krpc/utility/third_party/icu/icu_utf.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/third_party/symbolize/demangle.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/third_party/symbolize/symbolize.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/arena.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/at_exit.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/atomicops_internals_x86_gcc.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/big_endian.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/cpu.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/debug/alias.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/debug/asan_invalid_access.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/debug/crash_logging.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/debug/debugger.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/debug/debugger_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/debug/dump_without_crashing.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/debug/proc_maps_linux.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/debug/stack_trace.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/debug/stack_trace_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/environment.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/file.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/file_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/file_enumerator.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/file_enumerator_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/file_path.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/file_path_constants.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/memory_mapped_file.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/memory_mapped_file_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/scoped_file.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/scoped_temp_dir.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/file_util.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/file_util_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/guid.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/guid_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/lazy_instance.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/location.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/memory/aligned_memory.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/memory/ref_counted.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/memory/ref_counted_memory.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/memory/singleton.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/memory/weak_ptr.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/posix/file_descriptor_shuffle.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/posix/global_descriptors.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/process_util.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/rand_util.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/rand_util_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/fast_rand.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/safe_strerror_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/sha1_portable.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/latin1_string_conversions.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/nullable_string16.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/safe_sprintf.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/string16.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/string_number_conversions.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/string_split.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/string_piece.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/string_util.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/string_util_constants.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/stringprintf.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/utf_offset_string_conversions.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/utf_string_conversion_utils.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/strings/utf_string_conversions.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/synchronization/cancellation_flag.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/synchronization/condition_variable_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/synchronization/waitable_event_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/non_thread_safe_impl.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/platform_thread_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/simple_thread.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/thread_checker_impl.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/thread_collision_warner.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/thread_id_name_manager.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/thread_local_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/thread_local_storage.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/thread_local_storage_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/thread_restrictions.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/threading/watchdog.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/time/clock.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/time/default_clock.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/time/default_tick_clock.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/time/tick_clock.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/time/time.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/time/time_posix.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/version.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/logging.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/class_name.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/errno.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/find_cstr.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/status.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/string_printf.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/thread_local.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/thread_key.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/unix_socket.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/endpoint.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/fd_utility.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/temp_file.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/files/file_watcher.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/time.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/zero_copy_stream_as_streambuf.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/crc32c.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/containers/case_ignored_flat_map.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/iobuf.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/iobuf_profiler.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/binary_printer.cpp
        ${PROJECT_SOURCE_DIR}/krpc/utility/recordio.cc
        ${PROJECT_SOURCE_DIR}/krpc/utility/popen.cpp
)

if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
    set(KUTIL_SOURCES ${KUTIL_SOURCES}
            ${PROJECT_SOURCE_DIR}/krpc/utility/file_util_linux.cc
            ${PROJECT_SOURCE_DIR}/krpc/utility/threading/platform_thread_linux.cc
            ${PROJECT_SOURCE_DIR}/krpc/utility/strings/sys_string_conversions_posix.cc)
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
    set(KUTIL_SOURCES ${KUTIL_SOURCES}
            ${PROJECT_SOURCE_DIR}/krpc/utility/mac/bundle_locations.mm
            ${PROJECT_SOURCE_DIR}/krpc/utility/mac/foundation_util.mm
            ${PROJECT_SOURCE_DIR}/krpc/utility/file_util_mac.mm
            ${PROJECT_SOURCE_DIR}/krpc/utility/threading/platform_thread_mac.mm
            ${PROJECT_SOURCE_DIR}/krpc/utility/strings/sys_string_conversions_mac.mm
            ${PROJECT_SOURCE_DIR}/krpc/utility/time/time_mac.cc
            ${PROJECT_SOURCE_DIR}/krpc/utility/mac/scoped_mach_port.cc)
endif ()

file(GLOB_RECURSE KVAR_SOURCES "${PROJECT_SOURCE_DIR}/krpc/var/*.cpp" "${PROJECT_SOURCE_DIR}/krpc/var/*.cc")
file(GLOB_RECURSE KTHREAD_SOURCES "${PROJECT_SOURCE_DIR}/krpc/kthread/*.cc")
file(GLOB_RECURSE JSON2PB_SOURCES "${PROJECT_SOURCE_DIR}/krpc/json2pb/*.cc")
file(GLOB_RECURSE KRPC_SOURCES "${PROJECT_SOURCE_DIR}/krpc/rpc/*.cc")
file(GLOB_RECURSE THRIFT_SOURCES "${PROJECT_SOURCE_DIR}/krpc/rpc/thrift*.cc")
file(GLOB_RECURSE EXCLUDE_SOURCES "${PROJECT_SOURCE_DIR}/krpc/rpc/event_dispatcher_*.cc")

if (WITH_THRIFT)
    message("krpc compile with thrift protocol")
else ()
    # Remove thrift sources
    foreach (v ${THRIFT_SOURCES})
        list(REMOVE_ITEM KRPC_SOURCES ${v})
    endforeach ()
    set(THRIFT_SOURCES "")
endif ()

foreach (v ${EXCLUDE_SOURCES})
    list(REMOVE_ITEM KRPC_SOURCES ${v})
endforeach ()
set(MCPACK2PB_SOURCES
        ${PROJECT_SOURCE_DIR}/krpc/mcpack2pb/field_type.cc
        ${PROJECT_SOURCE_DIR}/krpc/mcpack2pb/mcpack2pb.cc
        ${PROJECT_SOURCE_DIR}/krpc/mcpack2pb/parser.cc
        ${PROJECT_SOURCE_DIR}/krpc/mcpack2pb/serializer.cc)
set(SOURCES
        ${KVAR_SOURCES}
        ${KTHREAD_SOURCES}
        ${JSON2PB_SOURCES}
        ${MCPACK2PB_SOURCES}
        ${KRPC_SOURCES}
        ${THRIFT_SOURCES}
)



set(PROTO_FILES krpc/idl_options.proto
        krpc/rpc/rtmp.proto
        krpc/rpc/rpc_dump.proto
        krpc/rpc/get_favicon.proto
        krpc/rpc/span.proto
        krpc/rpc/builtin_service.proto
        krpc/rpc/grpc_health_check.proto
        krpc/rpc/get_js.proto
        krpc/rpc/errno.proto
        krpc/rpc/nshead_meta.proto
        krpc/rpc/options.proto
        krpc/rpc/restful_service.proto
        krpc/rpc/policy/baidu_rpc_meta.proto
        krpc/rpc/policy/hulu_pbrpc_meta.proto
        krpc/rpc/policy/public_pbrpc_meta.proto
        krpc/rpc/policy/sofa_pbrpc_meta.proto
        krpc/rpc/policy/mongo.proto
        krpc/rpc/trackme.proto
        krpc/rpc/streaming_rpc_meta.proto
        krpc/rpc/proto_base.proto)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/output/include/krpc/rpc)
set(PROTOC_FLAGS ${PROTOC_FLAGS} -I${PROTOBUF_INCLUDE_DIRS})
kmcmake_cc_proto(PROTO_HDRS PROTO_SRCS ${PROJECT_BINARY_DIR}
        ${PROJECT_BINARY_DIR}/output/include
        ${PROJECT_SOURCE_DIR}
        "${PROTO_FILES}")
kmcmake_cc_object(
        NAMESPACE krpc
        NAME proto_obj
        SOURCES
        ${PROTO_SRCS}
        CXXOPTS
        ${KMCMAKE_CXX_OPTIONS}
)

add_subdirectory(krpc)
####################################################################
# belows are auto, edit it be cation
####################################################################
if (KMCMAKE_BUILD_TEST)

    set(TEST_PROTO_FILES
            tests/addressbook1.proto
            tests/addressbook_encode_decode.proto
            tests/addressbook_map.proto
            tests/addressbook.proto
            tests/echo.proto
            tests/iobuf.proto
            tests/message.proto
            tests/repeated.proto
            tests/v1.proto
            tests/v2.proto
            tests/grpc.proto
            tests/health_check.proto)
    file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/tests/hdrs)
    set(PROTOC_FLAGS ${PROTOC_FLAGS} -I${CMAKE_SOURCE_DIR})
    kmcmake_cc_proto(TEST_PROTO_HDRS TEST_PROTO_SRCS ${CMAKE_BINARY_DIR}
            ${CMAKE_BINARY_DIR}/tests/hdrs
            ${CMAKE_SOURCE_DIR}
            "${TEST_PROTO_FILES}")

    kmcmake_cc_library(
            NAMESPACE krpc
            NAME test_proto
            SOURCES
            ${TEST_PROTO_SRCS}
            CXXOPTS
            ${KMCMAKE_CXX_OPTIONS}
    )
    add_subdirectory(tests)
endif ()

if (KMCMAKE_BUILD_BENCHMARK)
    add_subdirectory(benchmark)
endif ()

if (KMCMAKE_BUILD_EXAMPLES)
    add_subdirectory(examples)
endif ()

##############################################
# header installing
#############################################
install(DIRECTORY ${PROJECT_NAME}
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
        FILES_MATCHING
        PATTERN "*.inc"
        PATTERN "*.h"
        PATTERN "*.hpp"
        )

# Layout. This works for all platforms:
#   * <prefix>/@CMAKE_INSTALL_LIBDIR@/cmake/<PROJECT-NAME>
#   * <prefix>/@CMAKE_INSTALL_LIBDIR@*/
#   * <prefix>/include/
set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")

set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")

# Configuration
set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake")
set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
set(namespace "${PROJECT_NAME}::")

# Include module with fuction 'write_basic_package_version_file'
include(CMakePackageConfigHelpers)

# Configure '<PROJECT-NAME>ConfigVersion.cmake'
# Use:
#   * PROJECT_VERSION
write_basic_package_version_file(
        "${version_config}" COMPATIBILITY SameMajorVersion
)

# Configure '<PROJECT-NAME>Config.cmake'
# Use variables:
#   * TARGETS_EXPORT_NAME
#   * PROJECT_NAME
configure_package_config_file(
        "cmake/krpc_config.cmake.in"
        "${project_config}"
        INSTALL_DESTINATION "${config_install_dir}"
)

#Targets:
#  * <prefix>/${CMAKE_INSTALL_LIBDIR}/libbar.a
#  * <prefix>/${CMAKE_INSTALL_LIBDIR}/libbaz.a
#  * header location after install: <prefix>/include/foo/Bar.hpp
#  * headers can be included by C++ code `#include <foo/Bar.hpp>`


# Config
#   * <prefix>/${CMAKE_INSTALL_LIBDIR}/cmake/Foo/FooConfig.cmake
#   * <prefix>/${CMAKE_INSTALL_LIBDIR}/cmake/Foo/FooConfigVersion.cmake
install(
        FILES
        "${project_config}" "${version_config}"
        DESTINATION
        "${config_install_dir}"
)

# Config
#   * <prefix>/${CMAKE_INSTALL_LIBDIR}/cmake/Foo/FooTargets.cmake

install(
        EXPORT
        "${TARGETS_EXPORT_NAME}"
        NAMESPACE
        "${namespace}"
        DESTINATION
        "${config_install_dir}"
)
configure_file(${PROJECT_SOURCE_DIR}/kmcmake/package/pkg_dump_template.pc.in
        ${PROJECT_BINARY_DIR}/package/${PROJECT_NAME}.pc)

install(FILES ${PROJECT_BINARY_DIR}/package/${PROJECT_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
include(krpc_cpack_config)
kmcmake_print("krpc cmake build system is created by kmcmake package manager tools")
kmcmake_print("kmcmake: https://gitee.com/kumo-pub/kmpkg")
kmcmake_print("docs: https://learn.kumo-ai.tech")